// File Name Decomposer :: Denis Yurin (c) 2011
#ifndef FILENAMEDECOMPRESSOR_H
#define FILENAMEDECOMPRESSOR_H

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

// fileName = baseFileName + <fileID> + <partSep> + <partID>
// fullFileName = path + baseFileName
// fullBaseFileName = path + baseFileName
using namespace std;

class FND {
	
	public:
		
		string path; 
		string baseFileName; 		
		string fileID; // file ID
		uint 	ifileID; 
		string partSep; // separation charecters f.e. _ for snap000_1
		string partID; // if file is splited then this is part ID
		uint 	ipartID;

		string fileName; // = baseFileName + <fileID> + <partSep> + <partID>
		string fullFileName; // = path + fileName
		string fullBaseFileName; // = path + baseFileName
		
		vector<string> dirList, dirList2; // ss list
		
		// Snapshot File Name Decompossing
		void decompose(string str){ 
			
			fileName = str;
			
			// cleaning
			path=fullFileName=baseFileName=fullBaseFileName=fileID=partSep=partID=""; 
			ifileID =ipartID=-1;
			dirList.erase(dirList.begin(), dirList.begin()+dirList.size());
			dirList2.erase(dirList2.begin(), dirList2.begin()+dirList2.size());

			
			// Path decompostion
			if (str.find_last_of("/")!=string::npos)  {
				
				path = str.substr(0, str.find_last_of("/")+1);
				
				string path_ = path;
				while ( path_.find_last_of("/") != string::npos) {
					
					dirList.push_back(path_);
					
					string tmp = path_.substr(0, path_.find_last_of("/"));
					uint dirlen = tmp.length() - tmp.find_last_of("/")-1;
					dirList2.push_back(path_.substr( path_.find_last_of("/")-dirlen, dirlen+1));		
					
					path_=path_.substr(0, tmp.find_last_of("/")+1);

				}
				
				fileName=str.substr(str.find_last_of("/")+1, str.length());		
			}
			
			
			// full File Name Decomposition
			if (fileName=="") return;
			fullFileName= str;
			
			// Base and IDs decomposion	
			if (fileName.find_first_of("0123456789")!=string::npos) {
				
				// Base 
				baseFileName = fileName.substr(0, fileName.find_first_of("0123456789"));
				fullBaseFileName =path+fileName.substr(0, fileName.find_first_of("0123456789"));
			
				// File ID
				string IDs = fileName.substr(fileName.find_first_of("0123456789"), fileName.length());
				fileID = IDs.substr(0, IDs.find_first_not_of("0123456789"));
				ifileID = atoi(fileID.c_str());
			
				// Part IDs
				if (IDs.find_first_not_of("0123456789")!=string::npos) {
					partSep = IDs.substr(IDs.find_first_not_of("0123456789"), IDs.find_last_not_of("0123456789")-2);  // it is not clear why -2 ??...
					partID = IDs.substr(IDs.find_last_not_of("0123456789")+1, IDs.length());  // it is not clear why -2 ??...
					ipartID = atoi(partID.c_str());
				} 
				
			}
			
		}
		
		// Print out decomposed information
		void print(){
			
			printf("\n");
			
			path!="" ?
			printf("\033[22;34mpath\033[22;30m: %s\n", path.c_str()) :
			printf("\033[22;34mpath\033[22;30m: \033[22;37mn/a\033[22;30m\n");
			
			fileName!="" ?
			printf("\033[22;34mfileName\033[22;30m: %s\n", fileName.c_str()) :
			printf("\033[22;34mfileName\033[22;30m: \033[22;37mn/a\033[22;30m\n");
			
			baseFileName!="" ?
			printf("\033[22;34mbaseFileName\033[22;30m: %s\n", baseFileName.c_str()) :
			printf("\033[22;34mbaseFileName\033[22;30m: \033[22;37mn/a\033[22;30m\n");
			
			fullBaseFileName!="" ? 
			printf("\033[22;34mfullBaseFileName\033[22;30m: %s\n", fullBaseFileName.c_str()) :
			printf("\033[22;34mfullBaseFileName\033[22;30m: \033[22;37mn/a\033[22;30m\n");
			
			fullFileName!="" ? 
			printf("\033[22;34mfullFileName\033[22;30m: %s\n", fullFileName.c_str()) :
			printf("\033[22;34mfullFileName\033[22;30m: \033[22;37mn/a\033[22;30m\n");
			
			printf("\n");
			
			for (uint i = 0; i<dirList.size();i++)
			printf("\033[22;34mdirList\033[22;30m[%u]: %s\n", i, dirList[i].c_str());
			printf("\n");
			
			for (uint i = 0; i<dirList2.size();i++)
			printf("\033[22;34mdirList\033[22;30m[%u]: %s\n", i, dirList2[i].c_str());
			printf("\n");
			
			if (fileID!="") { 
				printf("\033[22;34mfileID\033[22;30m: %s\n", fileID.c_str());
				printf("\033[22;34mifileID\033[22;30m: \033[22;33m%u\033[22;30m\n", ifileID);
			} else {
				printf("\033[22;34mfileID\033[22;30m: \033[22;37mn/a\033[22;30m\n");
				printf("\033[22;34mifileID\033[22;30m: \033[22;37mn/a\033[22;30m\n");
			}
			
			if (partID!="") { 
				printf("\033[22;34mpartSep\033[22;30m: %s\n", partSep.c_str());
				printf("\033[22;34mpartID\033[22;30m: %s\n", partID.c_str());
				printf("\033[22;34mipartID\033[22;30m: \033[22;33m%u\033[22;30m\n", ipartID);
			} else {
				printf("\033[22;34mpartSep\033[22;30m: \033[22;37mn/a\033[22;30m\n");
				printf("\033[22;34mpartID\033[22;30m: \033[22;37mn/a\033[22;30m\n");
				printf("\033[22;34mipartID\033[22;30m: \033[22;37mn/a\033[22;30m\n");
			}
			
		}
};

#endif